<?php

/**
 * Dashboard component
 *
 * PHP versions 5
 * CAKEPHP versions 2.x
 * 
 * Green CMS - Content Management System and Framework Powerfull by Cakephp
 * Copyright 2012, GREEN GLOBAL CO., LTD (toancauxanh.vn)
 * 
 * CakePHP(tm) :  Rapid Development Framework (http://www.cakephp.org)
 * Copyright 2005-2011, Cake Software Foundation, Inc. (http://www.cakefoundation.org)
 *
 * Licensed under The MIT License
 * Redistributions of files must retain the above copyright notice.
 *
 * @author        Technology Lab No.I <tech1@toancauxanh.vn>
 * @link          
 * @package       User.Controller.Component
 * @since         Green v 1.0
 * @license       MIT License (http://www.opensource.org/licenses/mit-license.php)
 */
App::uses('Component', 'Controller');

class DashboardComponent extends Component {

    /**
     * Other components utilized by Dashboard
     *
     * @var array
     */
    public $components = array();

    /**
     * get config
     * 
     * @param string $key
     * @return mixed
     */
    public function get($Model, $key) {
        return Configure::read($Model->configKey . 'Admin.' . $key);
    }

    /**
     * Render if ajax
     * 
     * @param array $vars set data to view
     * @param string $layout
     * @return void
     */
    public function render($vars = array(), $layout = '') {
        $controller = $this->controller();
        $controller->set($vars);
        if ($controller->request->is('ajax')) {
            $controller->layout = $layout;
            $controller->viewPath = 'Elements' . DS . $controller->name;
            $controller->render('index');
        }
    }

    /**
     * Get controller
     * 
     * @return Controller
     */
    public function controller() {
        return $this->_Collection->getController();
    }

    /**
     * Check id exists
     * 
     * @param Model $Model
     * @param mixed $id
     * @param boolean $required
     * @return void
     */
    public function exists(Model $Model, $id, $required = true) {
        $Model->id = $id;
        if (($id || $required) && !$Model->exists()) {
            $this->controller()->setFlash(__d('system', 'The id #%1$s of %2$s does not exist.', $id, $Model->alias));
            $this->redirect(array('action' => 'index', 'ext' => false), true);
        }
    }

    /**
     * Parse Redirect
     * 
     * @param array $url
     * @param boolean $continue
     * @param boolean $back
     * @return void
     */
    function redirect($url, $direct = false, $back = false) {
        $controller = $this->controller();
        $_url = null;
        if (!empty($controller->request->query['continue'])) {
            $_url = $controller->request->query['continue'];
        }
        if ($direct && $_url) {
            $url = $_url;
        } elseif (!($back && !$_url)) {
            if (!$back) {
                $_url = $controller->request->here(false);
            }
            if (!isset($url['?'])) {
                $url['?'] = array();
            }
            $url['?'] = array_merge($url['?'], array(
                'continue' => $_url));
        }
        $controller->redirect($url);
    }

    /**
     * Toolbar config
     * 
     * @param string $className
     * @param array $filterFields
     * @param array $defaultQueries
     * @return map value of filter fields
     */
    public function toolbar($title, $options = array()) {
        $controller = $this->controller();
        $_toolbar = array(
            'title' => $title,
            'options' => $options
        );
        if (!empty($controller->viewVars['_toolbars'])) {
            $_toolbar = array_merge($controller->viewVars['_toolbars'], $_toolbar);
        }
        $controller->set('_toolbars', $_toolbar);
    }

    /**
     * Parse Request
     * 
     * @param Model $Model
     * @param array $filterFields
     * @param array $defaultQueries
     * @return conditions for paginate
     */
    function parseRequest(Model $Model, $paginate, $filterFields = array(), $defaultQueries = array()) {
        $controller = $this->controller();

        $defaultFields = array_keys($Model->schema());
        $query = $controller->request->query;
        $configMaps = array(
            'd' => 'displayFields',
            'f' => 'filterFields',
            'limit' => 'limit'
        );
        $d = $f = $q = $limit = null;
        foreach ($configMaps as $var => $key) {
            if (!empty($query[$var]) || ($query[$var] = $this->get($Model, $key))) {
                ${$var} = $query[$var];
            }
            unset($query[$var]);
        }
        if (empty($d)) {
            $d = $defaultFields;
        } else {
            $d = array_intersect($defaultFields, (array) $d);
        }
        $f = array_intersect($defaultFields, (array) $f);
        if (empty($f)) {
            $f = $filterFields;
        }
        $conditions = array();
        if (!empty($query['q'])) {
            $keyword = $q = trim((string) $query['q']);
            if (strpos($keyword, '*') === false) {
                $keyword = '%' . $keyword . '%';
            } else {
                $keyword = str_replace('*', '%', $keyword);
            }
            foreach ($filterFields as $field) {
                $conditions[$field . ' LIKE'] = $keyword;
            }
        }
        unset($query['q']);
        foreach ($query as $field => $value) {
            if (strpos($field, '_') !== 0) {
                continue;
            }
            $field = substr($field, 1);
            if (in_array($field, $defaultFields)) {
                $defaultQueries[] = '_' . $field;
                if ($value != '') {
                    $conditions[$field] = $value;
                }
            }
        }

        $paginate = Set::merge(array('recursive' => 2), $paginate, array(
                    'paramType' => 'querystring',
                    'conditions' => $conditions,
                    'contain' => array(),
                    'fields' => $d,
                    'limit' => $limit,
                ));

        $_modelMaps = array(
            $Model->alias => $Model->displayField
        );
        foreach ($Model->belongsTo as $assoc => $config) {
            $_modelMaps[$assoc] = $Model->{$assoc}->displayField;
            if (!in_array($config['foreignKey'], $paginate['fields']) ||
                    isset($paginate['contain'][$assoc]) || in_array($assoc, $paginate['contain'])) {
                continue;
            }
            $paginate['contain'][$assoc] = array('fields' => array($Model->primaryKey, $_modelMaps[$assoc]));
        }
        $_filterQueries = array();
        $_displayFields = array_flip($d);
        $defaultQueries = array_merge(array('q', 'd', 'f', 'limit', 'sort', 'direction', 'page'), $defaultQueries);
        foreach ($defaultQueries as $key) {
            if (isset($controller->request->query[$key])) {
                $_filterQueries[] = $key;
            }
        }
        $controller->paginate = $paginate;
        $controller->set(compact('_filterQueries', '_displayFields', '_modelMaps'));
        $controller->request->data['Filter'] = array_merge($query, compact('q', 'd', 'f', 'limit'));
        return $paginate['conditions'];
    }

    /**
     * Get translated for translate action
     * 
     * @param Model $Model
     * @param string $locale
     * @param array $maps translate fields
     * @return array
     */
    public function getTranslated($Model, $maps) {
        $result = $Model->find('first', array(
            'locale' => array(
                'locale' => $Model->locale,
                'auto' => false
            ),
            'fields' => array_keys($maps),
            'conditions' => array($Model->alias . '.' . $Model->primaryKey => $Model->id),
            'recursive' => 1));
        foreach ($maps as $field => $alias) {
            $_result = null;
            if (!empty($result[$alias])) {
                foreach ($result[$alias] as $data) {
                    if ($data['locale'] === $Model->locale) {
                        $_result = $data['content'];
                        break;
                    }
                }
            }
            $result[$field] = $_result;
        }
        return $result;
    }

    /**
     * Remove translated by translate action
     * 
     * @param Model $Model
     * @return boolean
     */
    public function removeTranslated($Model) {
        $I18nModel = $Model->translateModel();
        return $I18nModel->deleteAll(array(
                    'model' => $Model->alias,
                    'locale' => $Model->locale,
                    'foreign_key' => $Model->id), false, false);
    }

    /**
     * Get translate fields
     * 
     * @param Model $Model
     * @return array
     */
    public function translateFields(Model $Model) {
        $Behavior = $Model->Behaviors->Translator;
        $fields = array();
        if ($Behavior && Router::isMultilingual()) {
            $fields = $Behavior->translateFields($Model);
        }
        $this->controller()->set('_translateFields', $fields);
        return $fields;
    }

    /**
     * Get i18n translated
     * 
     * @param Model $Model
     * @param array $data
     * @return mixed an array translate maps or boolean false
     */
    public function translateMaps(Model $Model, $data) {
        if ($this->translateFields($Model)) {
            $I18nModel = $Model->translateModel();
            $data = Set::extract($data, "{n}.{$Model->alias}.{$Model->primaryKey}");
            $translateMaps = $I18nModel->find('list', array(
                'recursive' => -1,
                'group' => array('foreign_key', 'locale'),
                'fields' => array('locale', 'foreign_key', 'foreign_key'),
                'conditions' => array(
                    'model' => $Model->alias,
                    'foreign_key' => $data
                    )));
            $this->controller()->set('_translateMaps', $translateMaps);
            return $translateMaps;
        }
        return false;
    }

    /**
     * Get translate locale
     * 
     * @param Model $Model
     * @param string $language
     * @return string locale
     */
    public function getLocale($language) {
        $locale = Router::getConfig('locale', $language);
        if (empty($locale)) {
            $config = I18n::getInstance()->l10n->catalog($language);
            if (empty($config['locale'])) {
                return false;
            }
            $locale = $config['locale'];
        }
        return $locale;
    }

}

?>
